package threewings;

import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.universe.SimpleUniverse;

/**
 * The camera that displays to the user
 * 
 * @author Tyler Whitehouse.
 *         Created Oct 21, 2013.
 */
public class Camera {
	
	private TransformGroup tg;
	private Transform3D tran = new Transform3D();
	private Point3f oldPos = new Point3f(); 
	
	private Glider parent;
	/**
	 * Make a new camera to hold the Transform group of the universe
	 * 
	 * @param tg
	 */
	public Camera (TransformGroup tg){
		this.tg = tg;
		this.tg.getTransform(this.tran);
	}
	
	
	/**
	 * Make a new camera to hold the Transform group of the universe
	 * 
	 * @param u
	 */
	public Camera (SimpleUniverse u){
		this.tg = u.getViewingPlatform().getViewPlatformTransform();
		this.tg.getTransform(this.tran);
	}
	
	/**
	 * Set the position of the camera relative to the origin
	 * @param v 
	 * 
	 */
	public void setPosition(Vector3f v){
		this.oldPos = this.getPosition();
		this.tran.setTranslation(v);
		this.tg.setTransform(this.tran);
	}
	
	/**
	 * Set the rotation of the camera around the given axis using right hand rule
	 * 
	 * @param aa AxisAngle4d
	 */
	public void setRotation(AxisAngle4f aa){
		this.tran.setRotation(aa);
		this.tg.setTransform(this.tran);
	}
	
	/**
	 * Set the transform of the camera
	 * 
	 * @param t
	 */
	public void setTransform(Transform3D t){
		this.tran = t;
		this.tg.setTransform(this.tran);
	}
	
	/**
	 * Get the position of the camera
	 * 
	 * @return Vector3f of the position
	 */
	public Point3f getPosition(){
		Vector3f vec = new Vector3f();
		this.tg.getTransform(this.tran);
		this.tran.get(vec);
		return new Point3f(vec);
	}
	
	
	/**
	 * Gets the velocity of the camera
	 *
	 * @return the velocity as a vector
	 */
	public Vector3f getVelocity(){
		Vector3f newoldpos=new Vector3f(this.oldPos);
		
		newoldpos.scale(-1);
		newoldpos.add(this.getPosition());
		return newoldpos;
		
		
	}
	/**
	 * Ready when you need me, SIR!
	 * 
	 * @return
	 *
	public AxisAngle4f getAngle(){
		this.tran.
	}
	/* */
	
	/**
	 * Point the Camera at a specific point
	 * @param c 
	 */
	public void pointAt(Point3f c){
		// record current position
		Vector3f oldpos = new Vector3f(this.getPosition());
		
		Point3d pos = new Point3d(this.getPosition());
		Point3d cd = new Point3d(c);
		this.tran.lookAt(pos, cd, new Vector3d(0,1,0));
		this.tran.invert();
		
		// reset to correct position
		this.tran.setTranslation(oldpos);
		
		this.tg.setTransform(this.tran);
	}
	
	/**
	 * Sets the glider this is following to the correct glider
	 *
	 * @param g
	 */
	public void setParentGlider(Glider g){
		this.parent = g;
	}
	
	/**
	 * This is called in the loop to update everything
	 *
	 */
	public void update(){//TODO add some code that will scale the camera back as it goes faster
		Vector3f parVel = new Vector3f(this.parent.getForward());
		parVel.y = 0f;
		if (Math.abs(parVel.x) < 0.01 && Math.abs(parVel.z) < 0.01){//TODO set this so that it just points forward instead of z=1
			parVel.z = 1;
			//System.out.println("Glider motionless");
		}
		parVel.normalize();
		parVel.negate();
		parVel.scale(4);
		
		Vector3f newPos = new Vector3f(this.parent.getPosition());
		newPos.add(parVel);
		newPos.y += 1f;
		this.setPosition(newPos);
		this.pointAt(this.parent.getPosition());
	}
}
